import { Matrix4 } from "../../utils/Matrix4";
import { TRS } from "./TRS";

/*
 * @Author: Snow
 * @Date: 2021-10-11 21:48:36
 * @Description: 
 */
export class Node{
    /* 本地矩阵 */
    public localMatrix:number[];
    /* 世界矩阵 */
    public worldMatrix:number[];
    /* 子节点列表 */
    public children:Node[];

    public drawInfo:any; //// sun system 示例在用

    public parent:Node;

    public name:string;

    public drawables:any[];

    public source:TRS;

    constructor(source?:TRS,name?:string){
        this.children = [];
        this.localMatrix = Matrix4.identity();
        this.worldMatrix = Matrix4.identity();
        this.name = name;
        this.drawables = [];
        this.source = source;
    }

    public addChild(node:Node):void{
        let index:number = this.children.indexOf(node);
        if( index> -1){
            this.children.splice(index,1);
        }
        this.children.push(node);
        node.parent = this;
    }

    public removeChild(node:Node):void{
        let index:number = this.children.indexOf(node);
        if( index> -1){
            this.children.splice(index,1);
            node.parent = null;
        }
    }

    public setParent(node:Node):void{
        node.addChild(this);
        this.parent = node;
    }

    public removeSelf():void{
        if(this.parent){
            this.parent.removeChild(this);
        }
    }

    /* 更新世界矩阵 */
    public updateWorldMatrix(parentWorldMatrix?:number[]):void{
        //console.log(this.name,"原始数据","localMatrix",this.localMatrix,"parentWorldMatrix",parentWorldMatrix);
        const source = this.source;
        if (source) {
            source.getMatrix(this.localMatrix);
        }

        if(parentWorldMatrix){
            this.worldMatrix = Matrix4.multiply(parentWorldMatrix,this.localMatrix);
        }else{
            Matrix4.copy(this.localMatrix,this.worldMatrix);
        }
        //console.log(this.name,"localMatrix",this.localMatrix);
        //console.log(this.name,"worldMatrix",this.worldMatrix);
        for (let index = 0; index < this.children.length; index++) {
            const element = this.children[index];
            element.updateWorldMatrix(this.worldMatrix);
        }
    }

    /**
     * @Author: Snow
     * @description: 所有节点执行
     * @param {function} fn
     * @return {*}
     */    
    public traverse(fn:(node:any)=>void): void {
        fn(this);
        for (const child of this.children) {
          child.traverse(fn);
        }
    }
}